
#-*- coding:utf-8 -*-
 
from flask import request
'''
request.args: the key/value pairs in the URL query string
request.form: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn't JSON encoded
request.files: the files in the body, which Flask keeps separate from form. HTML forms must use enctype=multipart/form-data or files will not be uploaded.
request.values: combined args and form, preferring args if keys overlap
'''
 
class ParamRequiredError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)
 
class Params(dict):
 
    def __init__(self, base_params = None, is_parse=True):
        self._parameters = base_params or {}
 
        if is_parse:
            values = request.values
            if values:
                self.__setup_params(values)
 
            files = request.files
            if files:
                self.__setup_params(files)
 
    def __setup_params(self, other):
        def deep_merge(a, b):
            for k, v in b.items():
                if isinstance(v, dict) and k in a:
                    deep_merge(a[k], v)
                elif isinstance(v, list) and k in a and isinstance(a[k], list):
                    a[k].extend(v)
                else:
                    a[k] = v
        deep_merge(self._parameters, other)
    
    def parameters(self):
        return self._parameters
 
    # params.require('k1','k2'...)
    def require(self,*keys):
        for key in keys:
            if key not in self._parameters:
                raise ParamRequiredError(key)
            if not self._parameters[key]:
                raise ParamRequiredError(key)
        return Params(self._parameters, is_parse = False)
 
    # params.permit('k1','k2'...)
    def permit(self, *args):
        params = dict()
        for k in args:
            if k in self._parameters:
                if self._parameters[k]:
                    params[k] = self._parameters[k]
        return Params(params, is_parse = False)
 
    def get_item(self,key, default=None):
        return self._parameters.get(key, default)
    
    def set_item(self,key,value):
        self._parameters[key] = value

    
def get_request_params(base_params=None):
    if not hasattr(request, 'params'):
        setattr(request, 'params', Params(base_params))
    return getattr(request, 'params')
 
 
def bind_request_params():
    params = get_request_params()


